package com.epam.traning.taskmanager.images;

import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.epam.traning.taskmanager.ContextHolder;

import android.content.Context;
import android.graphics.Bitmap;
import android.os.AsyncTask;
import android.widget.BaseAdapter;
import android.widget.ImageView;

public class ImageLoader {

	private static ImageLoader instance;
	
	public static ImageLoader getInstance() {
		if (instance == null) {
			instance = new ImageLoader();
		}
		return instance;
	}
	
	//TODO refactoring to LruChache and WeakRefernce
	private Map<String, Bitmap> mStorage;
	
	private List<Callback> mQueue;
	
	public interface Callback {
		
		String getUrl();
		
		void success(Bitmap bm);

		void onError(Exception e);
	}
	
	private ImageLoader() {
		mStorage = Collections.synchronizedMap(new HashMap<String, Bitmap>());
		mQueue = Collections.synchronizedList(new ArrayList<Callback>());
	}
	
	public void bind(final BaseAdapter adapter, final ImageView imageView, final String url) {
		Bitmap bitmap = null;
		if (mStorage.containsKey(url)) {
			bitmap = mStorage.get(url);
		}
		
		if (bitmap != null) {
			imageView.setImageBitmap(bitmap);
			return;
		} else {
			mQueue.add(0, new Callback() {
				
				@Override
				public void success(Bitmap bm) {
					adapter.notifyDataSetChanged();
				}
				
				@Override
				public String getUrl() {
					return url;
				}

				@Override
				public void onError(Exception e) {
					// TODO Auto-generated method stub
					
				}
			});
		}
		proceed();
	}
	
	public void bind(final ImageView imageView, final String url) {
		Bitmap bitmap = null;
		if (mStorage.containsKey(url)) {
			bitmap = mStorage.get(url);
		}
		if (bitmap != null) {
			imageView.setImageBitmap(bitmap);
			return;
		} else {
			//TODO check dublicates and moveup
			mQueue.add(0, new Callback() {
				
				@Override
				public void success(Bitmap bm) {
					imageView.setImageBitmap(bm);
				}
				
				@Override
				public String getUrl() {
					return url;
				}

				@Override
				public void onError(Exception e) {
					// TODO Auto-generated method stub
					//smth imageView.setBackgroundResource(android.R.drawable.ic_error);
				}
				
			});
		}
		proceed();
	}

	private void proceed() {
		if (mQueue.isEmpty()) {
			return;
		}
		final Callback callback = mQueue.remove(0);
		new AsyncTask<Callback, Void, Object>() {

			@Override
			protected Object doInBackground(Callback... params) {
				try {
					String url = params[0].getUrl();
					//check if exists cache file with name md5(url)
					Bitmap bitmap = null;
					// TODO HW load bitmap from internet
					Context context = ContextHolder.getInstance().getContext();
					File cacheDir = context.getCacheDir();
					//TODO cache like java bytes[] write to file
					return null;
				} catch (Exception e) {
					return e;
				}
			}

			@Override
			protected void onPostExecute(Object result) {
				super.onPostExecute(result);
				if (result instanceof Bitmap) {
					Bitmap bitmap = (Bitmap)result;
					mStorage.put(callback.getUrl(), bitmap);
					callback.success(bitmap);
					//TODO start thread to cache
				} else {
					callback.onError((Exception)result);
				}
			}
			
		}.execute(callback);
		//TODO or executeOnExecutor
	}
}
